package org.xiaov.lunasql.engine.transform.oracle;

import com.alibaba.druid.DbType;
import lombok.Getter;
import org.xiaov.lunasql.engine.ast.AdjustContext;
import org.xiaov.lunasql.engine.ast.adjust.Limit2RowNumAdjust;
import org.xiaov.lunasql.engine.ast.adjust.OracleIntervalAdjust;
import org.xiaov.lunasql.engine.ast.adjust.WithRecursiveAs2WithAsAdjust;
import org.xiaov.lunasql.engine.function.*;
import org.xiaov.lunasql.engine.keyword.DatabaseKeywords;
import org.xiaov.lunasql.engine.keyword.OracleKeywords;
import org.xiaov.lunasql.engine.transform.Transform;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * Mysql2OracleConfig
 * </p>
 *
 * @author LunaSQL
 * @since 2024/12/11 22:00
 */
@Getter
public class Mysql2OracleTransform implements Transform {
    private final List<MySqlFunction> functions = new ArrayList<>();
    private final AdjustContext adjustContext = new AdjustContext();
    private final Mysql2OracleAtsVisitorAdapter atsVisitorAdapter;
    private final DatabaseKeywords databaseKeywords = new OracleKeywords();

    /**
     * 构造函数
     */
    public Mysql2OracleTransform() {
        initTransformFunc();
        initAdjustContext();
        atsVisitorAdapter = new Mysql2OracleAtsVisitorAdapter(functions, adjustContext, databaseKeywords);
    }

    private void initAdjustContext() {
        Limit2RowNumAdjust limit2RowNumAdjust = new Limit2RowNumAdjust();
        WithRecursiveAs2WithAsAdjust withRecursiveAs2WithAsAdjust = new WithRecursiveAs2WithAsAdjust();
        OracleIntervalAdjust oracleIntervalAdjust = new OracleIntervalAdjust();
        adjustContext.setLimitAdjust(limit2RowNumAdjust);
        adjustContext.setIntervalAdjust(oracleIntervalAdjust);
        adjustContext.setWithRecursiveAsAdjust(withRecursiveAs2WithAsAdjust);
    }

    private void initTransformFunc() {
        functions.add(new GroupConcat2ListAggFunc());
        functions.add(new CurDate2SysDateFunc());
        functions.add(new DateFormat2ToCharFunc());
        functions.add(new IfNull2NvlFunc());
        functions.add(new InsertFunc());
        functions.add(new CurTime2SysDateFunc());
        functions.add(new ConcatMulti2ConcatFunc());
        functions.add(new Substring2Substr());
        functions.add(new If2CaseWhenFunc());
        functions.add(new DateAddFunc(functions, adjustContext.getIntervalAdjust()));
        functions.add(new DateSubFunc(functions, adjustContext.getIntervalAdjust()));
        functions.add(new ConcatWsFunc(functions));
    }

    @Override
    public DbType registerType() {
        return DbType.oracle;
    }

}
